#include "filter.h"
#include "arp_handle.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h> // kill
#include <sys/types.h>
#include <unistd.h>    // getpid
#include <arpa/inet.h> // inet_pton
#include <sys/stat.h>
#include <fcntl.h>
/*******************************************************
函数: void help()
功能: 帮助信息
参数: 无
返回值: 无
********************************************************/
void help()
{
    // system("cls");
    printf("-------------------欢迎使用我的路由V1.0版本-------------------------\n");

    printf("\t1. 查看arp表\n");
    printf("\t2. 设置过滤规则\n");
    printf("\t3. 删除过滤规则\n");
    printf("\t4. 查看过滤规则\n");
    printf("\t5. 保存过滤规则\n");
    printf("\t6. 退出系统\n");

    printf("------------------------------------------------------------------\n\n");
    printf("请选择:");
}

/*******************************************************
函数: void* filter_handler(void* arg)
功能: 过滤规则选择
参数: 无
返回值: 无
********************************************************/
void *filter_handler(void *arg)
{
    char *file_name = (char *)arg; // 保存的文件名
    filter_head = (filter_node *)malloc(sizeof(filter_node));
    reload_file(file_name); // 加载配置
    char ch;
    while (1)
    {
        help();
        scanf("%c", &ch);
        getchar(); // 处理换行符
        if (ch == '1')
        {
            print_arp_list();
        }
        else if (ch == '2') // 设置过滤规则
        {
            set_rule(ch);
        }
        else if (ch == '3') // 删除过滤规则
        {
            set_rule(ch);
        }
        else if (ch == '4') // 查看过滤规则
        {
            print_filter_node();
        }
        else if (ch == '5') // 保存过滤规则
        {
            save_file(file_name);
        }
        else if (ch == '6')
        {
            system("clear"); // 清屏
            printf("感谢使用!\n");
            break;
        }
    }
    // 系统退出 通知主线程结束
    kill(getpid(), SIGINT);
}
/*******************************************************
函数: void set_rule()
功能: 设置过滤规则
参数: 无
返回值: 无
********************************************************/
void set_rule(char ch)
{
    char op[4];
    char buf[16];
    if (ch == '2') // 添加操作
    {
        printf("exmaple:set 192.168.0.1\n");
        scanf("%s %s", op, buf);
        buf[15] = '\0';                 // 去除换行符
        getchar();                      // 处理换行符
        if (strncmp(op, "set", 3) == 0) // 添加操作
        {
            unsigned int ip;
            inet_pton(AF_INET, buf, &ip);
            if (insert_filter_node(ip) != NULL)
                printf("添加成功!\n");
        }
    }
    else if (ch == '3')
    {
        printf("exmaple:del 192.168.0.1\n");
        scanf("%s %s", op, buf);
        buf[15] = '\0';                 // 去除换行符
        getchar();                      // 处理换行符
        if (strncmp(op, "del", 3) == 0) // 删除操作
        {
            unsigned int ip = inet_addr(buf);
            filter_node *pre = filter_head;
            filter_node *cur = filter_head->next;
            while (cur != NULL)
            {
                if (cur->ip == ip) // 找到要删除的ip
                {
                    pre->next = cur->next;
                    free(cur);
                    printf("删除成功!\n");
                    return;
                }
                pre = cur;
                cur = cur->next;
            }

            printf("删除失败,未查询到该IP!\n");
            return;
        }
    }
}
/*******************************************************
函数: void print_filter_node()
功能: 打印过滤规则
参数: 无
返回值: 无
********************************************************/
void print_filter_node()
{
    if (filter_head == NULL || filter_head->next == NULL)
    {
        printf("未设置规则\n");
        return;
    }
    printf("******************过滤规则如下******************\n");
    filter_node *tmp = filter_head->next;
    unsigned char ip[16];
    while (tmp != NULL)
    {
        memset(ip, 0, sizeof(ip));
        inet_ntop(AF_INET, &tmp->ip, ip, sizeof(ip));
        printf("IP:\t%s\n", ip);
        tmp = tmp->next;
    }
    printf("******************过滤规则结束******************\n");
}
/*******************************************************
函数: void save_file(char* file)
功能: 将规则数据写入文件
参数: 无
返回值: 无
********************************************************/
void save_file(char *file)
{
    if (file == NULL) // 没有文件名则不记录
        return;
    int fd = open(file, O_CREAT | O_WRONLY, 06666);
    if (fd < 0)
    {
        perror("open write");
        return;
    }
    // 没有数据则不写
    if (filter_head == NULL || filter_head->next == NULL)
        return;
    filter_node *tmp = filter_head->next;
    // 将ip转成点分十进制保存到文件
    while (tmp != NULL)
    {
        unsigned char buf[20] = "";
        inet_ntop(AF_INET, &tmp->ip, buf, 16);
        buf[15] = '\n';
        write(fd, buf, 16);
        tmp = tmp->next;
    }
    close(fd);
}
/*******************************************************
函数: void print_filter_node(char* file)
功能: 数据文件读取出来
参数: 无
返回值: 无
********************************************************/
void reload_file(char *file)
{
    if (file == NULL) // 没有文件名则不读取
        return;
    int fd = open(file, O_RDONLY);
    if (fd < 0)
    {
        // perror("open write");
        return;
    }
    unsigned char buf[16];
    unsigned int ip;
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        int len = read(fd, buf, sizeof(buf));
        if (len <= 0)
            break;
        buf[15] = '\0';
        ip = 0;
        inet_pton(AF_INET, buf, &ip);
        insert_filter_node(ip);

    }
    close(fd);
}
/*******************************************************
函数: filter_node* insert_filter_node()
功能: 插入过滤节点
参数: ip
返回值: 失败返回NULL 成功返回节点地址
********************************************************/
filter_node *insert_filter_node(unsigned int ip)
{
    if (filter_head == NULL)
    {
        printf("filter_head is null\n");
        return NULL;
    }
    filter_node *node = (filter_node *)malloc(sizeof(filter_node));
    node->ip = ip;
    node->next = NULL;
    if (filter_head->next == NULL)
    {
        filter_head->next = node;
        return node;
    }

    filter_node *tmp = filter_head->next;
    while (tmp->next != NULL)
    {
        tmp = tmp->next;
    }
    tmp->next = node;

    return node;
}
/*******************************************************
函数: filter_node * find_filter_node(unsigned int ip)
功能: 查询ip是否在黑名单中
参数: ip
返回值: 失败返回NULL 成功返回节点地址
********************************************************/
filter_node *find_filter_node(unsigned int ip)
{
    if (filter_head == NULL)
    {
        printf("filter_head is null\n");
        return NULL;
    }
    filter_node *tmp = filter_head->next;
    while (tmp != NULL)
    {
        if (tmp->ip == ip)
            return tmp;
        tmp = tmp->next;
    }
    return NULL;
}